/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.pig4cloud.pigx.contract.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.common.customize.security.utils.SecurityUtil;
import com.pig4cloud.pigx.common.customize.utils.CommonUtil;
import com.pig4cloud.pigx.contract.dto.AppContractOptionalSymbolListDTO;
import com.pig4cloud.pigx.contract.entity.ContractOptionalSymbol;
import com.pig4cloud.pigx.contract.mapper.ContractOptionalSymbolMapper;
import com.pig4cloud.pigx.contract.service.ContractOptionalSymbolService;
import com.pig4cloud.pigx.contract.utils.ContractUtils;
import com.pig4cloud.pigx.contract.vo.AppContractSymbolIncreaseRankingVO;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 自选行情表
 *
 * @date 2022-08-12 11:42:59
 */
@Service
@AllArgsConstructor
public class ContractOptionalSymbolServiceImpl extends ServiceImpl<ContractOptionalSymbolMapper, ContractOptionalSymbol> implements ContractOptionalSymbolService {

	private final MongoTemplate mongo;
	private final ContractUtils contractUtils;
	private final ContractOptionalSymbolMapper contractOptionalSymbolMapper;

	@Override
	public List<AppContractSymbolIncreaseRankingVO> getList(AppContractOptionalSymbolListDTO dto) {
		Query query = Query.query(Criteria.where("status").is("1"));
		// 排序
		List<Sort.Order> orderList = this.getOrders(dto);
		// 自选币对idList
		List<Long> optionalIdList = null;

		// 查询推荐8个币对
		if (Objects.equals(AppContractOptionalSymbolListDTO.TYPE_RECOMMEND, dto.getType())) {
			// 如果没有指定排序，默认按照成交量降序
			if (CollectionUtils.isEmpty(orderList)) {
				orderList.add(Sort.Order.desc("sumPrice"));
			}
			// 分页数据
			query.limit(8);

		} else if (Objects.equals(AppContractOptionalSymbolListDTO.TYPE_OPTIONAL, dto.getType())
				|| Objects.equals(AppContractOptionalSymbolListDTO.TYPE_ALL, dto.getType())) {
			// 查询自选币对
			Long userId = SecurityUtil.getLoginUserNotNull().getId();
			QueryWrapper<ContractOptionalSymbol> queryWrapper = new QueryWrapper<>();
			queryWrapper.lambda()
					.select(ContractOptionalSymbol::getSymbolId)
					.eq(ContractOptionalSymbol::getUserId, userId);

			List<ContractOptionalSymbol> list = contractOptionalSymbolMapper.selectList(queryWrapper);
			// 查询类型 = 自选币对
			if (Objects.equals(AppContractOptionalSymbolListDTO.TYPE_OPTIONAL, dto.getType())
					&& CollectionUtils.isEmpty(list)) {
				// 直接返回空列表
				return Collections.emptyList();
			}

			// 收集自选币对id
			optionalIdList = list.stream()
					.map(ContractOptionalSymbol::getSymbolId)
					.collect(Collectors.toList());

			// 查询类型 = 自选币对，将自选币对id作为查询查询条件
			if (Objects.equals(AppContractOptionalSymbolListDTO.TYPE_OPTIONAL, dto.getType())) {
				query.addCriteria(Criteria.where("_id").in(optionalIdList));
			}

		} else {
			throw new RuntimeException("无法识别的查询类型");
		}

		// 排序
		query.with(Sort.by(orderList));

		List<AppContractSymbolIncreaseRankingVO> voList = mongo.find(query, AppContractSymbolIncreaseRankingVO.class);
		if (CollectionUtils.isEmpty(voList)) {
			return voList;
		}

		// 遍历
		for (AppContractSymbolIncreaseRankingVO vo : voList) {
			// 设置精度
			contractUtils.setScaleBySymbol(vo, vo.getSymbolName());

			// 设置是否自选
			if (!CollectionUtils.isEmpty(optionalIdList)) {
				vo.setIsOptional(optionalIdList.contains(Long.valueOf(vo.getSymbolId())));
			}
		}

		// 清除币对缓存
		ContractUtils.removeSymbolThreadCache();
		return voList;
	}

	/**
	 * 拼接排序规则
	 *
	 * @param data 参数
	 * @return
	 */
	private List<Sort.Order> getOrders(AppContractOptionalSymbolListDTO data) {
		List<Sort.Order> orderList = new ArrayList<>();
		// 按成交量排序
		if (data.getOrderSumPrice() != null) {
			if (data.getOrderSumPrice() == 0) {
				orderList.add(Sort.Order.asc("sumPrice"));
			} else {
				orderList.add(Sort.Order.desc("sumPrice"));
			}
		}
		// 按最新价排序
		if (data.getOrderLastPrice() != null) {
			if (data.getOrderLastPrice() == 0) {
				orderList.add(Sort.Order.asc("lastPrice"));
			} else {
				orderList.add(Sort.Order.desc("lastPrice"));
			}
		}
		// 按涨跌幅排序
		if (data.getOrderRiseAndFallRange() != null) {
			if (data.getOrderRiseAndFallRange() == 0) {
				orderList.add(Sort.Order.asc("riseAndFallRange"));
			} else {
				orderList.add(Sort.Order.desc("riseAndFallRange"));
			}
		}
		return orderList;
	}
}
